#include "StdAfx.h"
#include "SessionEventHandler.h"
#include <WinSock2.h>
#include <memory>


CSessionEventHandler::CSessionEventHandler(void)
{
	m_protoCoder.Init();
}


CSessionEventHandler::~CSessionEventHandler(void)
{
}

void CSessionEventHandler::on_established()
{
	//cout<<"established from ip "<<m_pConnector->get_session()->get_remote_ip_as_string()
	//	<<"port "<<m_pConnector->get_session()->get_remote_port()<<endl;
}

void CSessionEventHandler::on_disconnected()
{
	//cout<<"disconnected from ip "<<m_pConnector->get_session()->get_remote_ip_as_string()<<endl;
}

void CSessionEventHandler::on_error(int32 error_code, const char *error_message)
{
	//cout<<"error occurred with id="<<error_code<<", message="<<error_message<<endl;
	if (error_code == 10061 || error_code == 10054)
	{
		m_pConnector->reconnect(5);
	}
}

void CSessionEventHandler::on_receive(const char *message, uint32 message_length)
{
	if (message_length < sizeof(uint32))
		return;
	uint32 nMsgID = ntohl(*((int *)message));

	try{
		m_protoCoder.Decode(nMsgID, message + sizeof(nMsgID), message_length - sizeof(nMsgID), this);
	}
	catch(...)
	{
		
	}
}

void CSessionEventHandler::SetConnector(const utility::network::connector * pConnector)
{
	m_pConnector = const_cast<utility::network::connector* >(pConnector);
}

void CSessionEventHandler::message1_proc( const PKG_MESSAGE1_RPT * pPkg )
{

}

bool CSessionEventHandler::Send( uint32 MsgID, ::google::protobuf::Message * pMessage )
{
	size_t nBufSize = pMessage->ByteSize() + sizeof(uint32);
	//std::scoped_array<char> pBuf(new char[nBufSize]);
	std::auto_ptr<char> pBuf(new char[nBufSize]);
	//char * pBuf = (char *)alloca(nBufSize);

	uint32 * pHeader = (uint32*)(pBuf.get());
	*pHeader = htonl(MsgID);

	void * pMsg = (void*)(pBuf.get() + sizeof(uint32));

	bool bFlag = pMessage->SerializeToArray(pMsg, nBufSize - sizeof(uint32));
	if (!bFlag)
	{
		return false;
	}
	if (m_pConnector->get_session())
		m_pConnector->get_session()->send(pBuf.get(), nBufSize);
	else
		return false;
	return true;
}
